//
//  main.m
//  OC08_Category_Extension_Protocol
//
//  Created by Scott on 16/3/5.
//  Copyright © 2016年 Scott. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "AddressBook.h"
#import "Contact.h"
#import "NSString+AddMethods.h"
#import "Girl.h"
#import "Boy.h"


/**
 * 知识点: category (类目, 或分类)
 *
 * 作用1: 对没有源码(没有.m文件)的类扩展功能
            只能添加方法, 不能添加实例变量.
 *
 * 作用2: 编写类文件时, 把众多方法进行分类.
 */
void chapterOfCategory() {
    
    // 详见 NSString+AddMethods 类文件.
    [NSString sayHi];
    
    
    // 练习: 为NSString类扩展一个新的方法，要求获取字符串的首字母并且将该首字母大写。
    NSString *first = [NSString getFirstCharacterWithString:@"iphone"];
    NSLog(@"first:%@", first);
    
    NSString *fir = [@"Android" getFirstCharacterWithString];
    NSLog(@"fir:%@", fir);
}

/** 知识点: extension. */
void chapterOfExtension() {
    
    // 详见通讯录类.
    AddressBook *ab = [[AddressBook alloc] init];
    
    Contact *con1 = [[Contact alloc] init];
    con1.name = @"Tom";
    con1.phoneNumber = @"13382763813";
    
    [ab addContact:con1];
    
    
    
    

    
    
}

/** 知识点: protocol, delegate. */
void chapterOfProtocelDelegate() {
    
    /**
     * 详见Girl和Boy类.
     *
     * Girl类声明协议方法(只声明不实现), Boy对象实现协议方法. 
     
     * !!! Girl 类在适当的时机, 让代理人调用协议方法.
     *
     * 总结: delegate设计模式 分6步:
     * 1. girl 类声明协议方法.
     * 2. girl 声明一个delegate属性(通常用assign)
     * 3. girl 在适当的时机(适当的方法中), 让delegate执行协议方法.
     * 4. boy 签订协议
     * 5. girl指定delegate(boy对象.)
     * 6. boy实现协议方法.
     */
    
    Girl *girl = [[Girl alloc] init];
    girl.name = @"小梅";
    
    Boy *boy = [[Boy alloc] init];
    boy.name = @"小强";
    
    // girl指定代理人.
    girl.delegate = boy;
    
    [girl marry];
    
    
    
}

/** 限时代码. */
void limitTimeCoded() {
    
    
}

/** 阅读资料. */
void resource() {
    
    
}

#pragma mark - MAIN FUNCTION
int main(int argc, const char * argv[]) {

#pragma mark - 知识点1: Category (类目)
    chapterOfCategory();
    
#pragma mark - 知识点2: Extension (延展)
    chapterOfExtension();
    
#pragma mark - 知识点3: Protocol , delegate
    chapterOfProtocelDelegate();
    
#pragma mark - 限时代码.
    limitTimeCoded();
    
#pragma mark - 阅读资料.
    resource();
    
    
    return 0;
}
